package com.seu.project.seuquiz.controller;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seu.project.seuquiz.annotation.AuthCheck;
import com.seu.project.seuquiz.common.BaseResponse;
import com.seu.project.seuquiz.common.DeleteRequest;
import com.seu.project.seuquiz.common.ErrorCode;
import com.seu.project.seuquiz.common.ResultUtils;
import com.seu.project.seuquiz.constant.UserConstant;
import com.seu.project.seuquiz.exception.BusinessException;
import com.seu.project.seuquiz.mapper.ContestMapper;
import com.seu.project.seuquiz.model.converter.UserScoreMapConverter;
import com.seu.project.seuquiz.model.dto.collegeContestMap.CollegeContestMapQueryRequest;
import com.seu.project.seuquiz.model.dto.user.UserQueryRequest;
import com.seu.project.seuquiz.model.dto.userScoreMap.UserScoreMapAddRequest;
import com.seu.project.seuquiz.model.dto.userScoreMap.UserScoreMapQueryRequest;
import com.seu.project.seuquiz.model.dto.userScoreMap.UserScoreMapUpdateRequest;
import com.seu.project.seuquiz.model.entity.CollegeContestMap;
import com.seu.project.seuquiz.model.entity.Contest;
import com.seu.project.seuquiz.model.entity.User;
import com.seu.project.seuquiz.model.entity.UserScoreMap;
import com.seu.project.seuquiz.model.res.UserContestMapRes;
import com.seu.project.seuquiz.service.*;
import com.seu.project.seuquiz.util.EasyExcelUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户分数接口
 * @author SoftPro
 * @createDate: 2023-07-16 09:48
 */
@RestController
@RequestMapping("/user_score")
@Slf4j
@Api(tags = "用户-竞赛成绩接口")
public class UserScoreMapController {
    
    @Resource
    private UserScoreMapService userScoreMapService;

    @Resource
    private UserService userService;

    @Resource
    private CollegeContestMapService collegeContestMapService;

    @Resource
    private CollegeService collegeService;

    @Resource
    private ContestService contestService;

    @Resource
    private ContestMapper contestMapper;

    // region_start 基本增删改查

    /**
     * 新增用户分数
     * @param request
     * @return
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = "admin")
    @ApiOperation("addUserScoreMap ： 新增用户竞赛分数记录")
    @ApiImplicitParams({})
    public BaseResponse<Long> addUserScoreMap(@RequestBody UserScoreMapAddRequest request) {
        if (request == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        String studentId = request.getStudentId();
        String contestId = request.getContestId();
        Integer time = request.getTime();
        Integer score = request.getScore();

        // 更新用户竞赛表
        long id = userScoreMapService.questionAdd(studentId,contestId, time, score);
        if (id < 0) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据库异常");
        }
        // 查询学生所在学院
        UserQueryRequest userQueryRequest = UserQueryRequest.builder()
                .studentID(studentId)
                .build();
        QueryWrapper<User> queryWrapper = userService.getEqualQueryWrapper(userQueryRequest);
        User user = userService.getOne(queryWrapper);
        String college = user.getCollege();

        // 更新学院竞赛表
        CollegeContestMapQueryRequest collegeContestMap = CollegeContestMapQueryRequest.builder()
                .collegeName(college)
                .contestId(contestId)
                .build();
        QueryWrapper<CollegeContestMap> collegeContestMapQueryWrapper =
                collegeContestMapService.getQueryWrapper(collegeContestMap);
        CollegeContestMap exist =
                collegeContestMapService.getOne(collegeContestMapQueryWrapper);
        if (exist != null) {
            // 执行更新操作
            exist.setTotalScore(exist.getTotalScore() + score);
            exist.setJoinTotal(exist.getJoinTotal() + 1);
            collegeContestMapService.updateById(exist);
        } else {
            // 执行插入操作
            Integer totalStudent = collegeService.getCollegeTotalStudent(college);

            exist = new CollegeContestMap();
            exist.setCollegeName(college);
            exist.setContestId(contestId);
            exist.setCollegeStudentTotal(totalStudent);
            exist.setJoinTotal(1);
            exist.setTotalScore(score);

            collegeContestMapService.save(exist);
        }

        return ResultUtils.success(id);
    }

    /**
     * 删除用户竞赛分数
     * @param deleteRequest
     * @return
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = "admin")
    @ApiOperation("deleteUserScoreMapById ： 删除用户竞赛分数记录")
    public BaseResponse<Boolean> deleteUserScoreMapById(@RequestBody DeleteRequest deleteRequest){
        if(deleteRequest==null || deleteRequest.getId()<0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = userScoreMapService.removeById(deleteRequest.getId());
        return ResultUtils.success(b);
    }

    /**
     * 批量删除
     * @param deleteRequest
     * @return
     */
    @PostMapping("/deleteByIds")
    @AuthCheck(mustRole = "admin")
    @ApiOperation("deleteUserScoreMapByIds ： 批量删除用户竞赛分数记录")
    public BaseResponse<Boolean> deleteUserScoreMapByIds(@RequestBody DeleteRequest deleteRequest){
        if(deleteRequest==null || deleteRequest.getIds().size() < 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = userScoreMapService.removeByIds(deleteRequest.getIds());
        return ResultUtils.success(b);
    }

    /**
     * 更新用户竞赛分数
     * @param updateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = "admin")
    @ApiOperation("updateUserScoreMap ： 更新用户竞赛分数记录")
    public BaseResponse<Boolean> updateUserScoreMap(@RequestBody UserScoreMapUpdateRequest updateRequest){
        if(updateRequest==null || updateRequest.getId()<0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = userScoreMapService.updateById(UserScoreMapConverter.userScoreMapQueryRequestToUserScoreMap(updateRequest));
        return ResultUtils.success(b);
    }

    /**
     * 根据id查询用户分数
     * @param id
     * @return
     */
    @GetMapping("/get")
    @ApiOperation("getUserScoreMapById ： 根据id查询用户竞赛分数记录")
    public BaseResponse<UserContestMapRes> getUserScoreMapById(int id){
        if(id<=0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UserScoreMap userScoreMap = userScoreMapService.getById(id);
        return ResultUtils.success(toUserContestMapRes(userScoreMap));
    }

    private UserContestMapRes toUserContestMapRes(UserScoreMap userScoreMap) {
        QueryWrapper<User> queryWrapper = userService.getQueryWrapper(UserQueryRequest.builder()
                .studentID(userScoreMap.getStudentId()).build());
        User user = userService.getOne(queryWrapper);
        Contest contest = contestService.getById(userScoreMap.getContestId());
        if (contest == null) {
            // 查找被删除掉的竞赛
            contest = contestMapper.getExpireContestById(Long.valueOf(userScoreMap.getContestId()));
            if (contest == null) {
                // 该竞赛不存在
                contest = Contest.builder().contestName("未知竞赛").build();
            }
        }
        return UserContestMapRes.toModel(userScoreMap, contest, user);
    }

    /**
     * 根据查询条件获取全部的用户分数信息  todo: 待测试
     * @param request
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("listUserScoreMap ： 按条件查询用户竞赛分数信息")
    public BaseResponse<List<UserContestMapRes>> listUserScoreMap(UserScoreMapQueryRequest request) {
        QueryWrapper<UserScoreMap> queryWrapper = userScoreMapService.getQueryWrapper(request);
        List<UserScoreMap> list = userScoreMapService.list(queryWrapper);
        List<UserContestMapRes> collect = list.stream()
                .map(this::toUserContestMapRes)
                // .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                .collect(Collectors.toList());
        return ResultUtils.success(collect);
    }

    /**
     * 分页获取用户分数     todo:待测试
     * @param request
     * @return
     */
    @GetMapping("/list/page")
    @ApiOperation("listUserScoreMapByPage：按条件分页查询用户竞赛分数信息")
    public BaseResponse<Page<UserContestMapRes>> listUserScoreMapByPage(UserScoreMapQueryRequest request) {
        long current = 1;
        long size = 10;
        if (request != null) {
            current = request.getCurrent();
            size = request.getPageSize();
        }
        QueryWrapper<UserScoreMap> queryWrapper = userScoreMapService.getQueryWrapper(request);
        Page<UserScoreMap> page = userScoreMapService.page(new Page(current, size), queryWrapper);
        List<UserContestMapRes> collect = page.getRecords().stream()
                .map(this::toUserContestMapRes)
                .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                .collect(Collectors.toList());
        Page<UserContestMapRes> resPage = new Page<>();
        BeanUtils.copyProperties(page,resPage);
        resPage.setRecords(collect);
        return ResultUtils.success(resPage);
    }

    // region_end

    /**
     * 以excel文件方式批量添加用户竞赛成绩
     * @param multipartFile
     * @return
     */
    @PostMapping("/add/batch")
    public BaseResponse<String> addUserContestBatch(@RequestPart("file") MultipartFile multipartFile){
        // 校验文件
        long size = multipartFile.getSize();
        String originalFilename = multipartFile.getOriginalFilename();
        // 校验文件大小
        final long ONE_MB = 1024 * 1024L;
        if (size > ONE_MB) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件超过 1M");
        }
        // 校验文件后缀   aaa.png
        String suffix = FileUtil.getSuffix(originalFilename);
        final List<String> validFileSuffixList = Arrays.asList("xlsx", "xls");
        if (!validFileSuffixList.contains(suffix)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件后缀非法");
        }

        List<UserScoreMap> userScoreMapList = EasyExcelUtils.excelToUserContestList(multipartFile);
        boolean saveBatch = userScoreMapService.saveBatch(userScoreMapList);
        if (!saveBatch) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库错误");
        }
        return ResultUtils.success("添加完成");
    }
}
